import {Action,Cst,Web} from './config'
export default class Algo{
	static [Action.FunctionTool](step,pos,state,$env){
		let ps = []
		let pageRect = document.pageRect()
		let translate = $env.get("translate")
		let cfd = $env.get(Cst.CacheFuncDataGhost)
		let ratio = state.ratio*state.zoom
		let stepMeta = step[0]
		let psflat=[]
		ps = cfd.get(stepMeta.raw)||[]
		if(stepMeta.arg==="xy")
			psflat = ps.flat().flat()
		else
			psflat = ps.flat()
		let result = psflat.flat().some((p)=>Math.distance(p,pos)<Web.r)
		return result
	}
	static [Action.Image](step,pos){
		let fp = step[0]
		let sp = {x:fp.x+fp.w,y:fp.y+fp.h}
		return Math.between(fp,sp,pos,fp.r)
	}
	static [Action.Text](step,pos,state){
		let {x,y,w,h} = step[0]
		let scale = state.fontSize/14
		let fp={
			x,
			y:y-h*scale/2
		}
		let sp={
			x:x+w*scale,
			y:y+h*scale/2
		}
		return Math.between(fp,sp,pos,fp.r)
	}
	static [Action.Angle](step,pos){
		let fp =step[0]
		let lp =step[1]
		let ep =step[2]
		let r = fp.r
		let r0 = Math.distance(fp,lp)
		let r1 = Math.distance(fp,pos)

		let s = Math.tan360(lp.y-fp.y,lp.x-fp.x)
		let e = Math.tan360(ep.y-fp.y,ep.x-fp.x)
		let pa = Math.tan360(pos.y-fp.y,pos.x-fp.x)

		let c1 = Math.abs(r1-r0)<r
		let c2 = Math.foldlineInPath([fp,lp],pos,true)
		let c3 = Math.foldlineInPath([fp,ep],pos,true)

		let c4 = false
		if(e>=s)
			c4 = pa>=s&&pa<=e
		else
			c4 = (e-s>-180)?(pa<=e||pa>=s):(pa>=s||pa<=e)
		let c5 = c4&&c1
		return c5||c2||c3
	}
	// ************************circle circle circle start
	static [Action.Circle](step,pos){
		let fp =step[0]
		let lp =step[1]
		let r = Math.distance(fp,lp)
		let r1 = Math.distance(fp,pos)

		let c1 = Math.abs(r1-r)<fp.r
		let c2 = Math.distance(fp,pos)<fp.r
		return c1||c2
	}
	static [Action.Circle3p](step,pos){
		let fp = step[0]
		let cp = Math.calcCircleCenter(step)
		let r  = Math.distance(fp,cp)
		let r1 = Math.distance(cp,pos)

		let c1 = Math.abs(r1-r)<fp.r
		let c2 = Math.distance(cp,pos)<fp.r
		return c1||c2
	}
	// static [Action.CircleOuter](step,pos){
	// 	return Algo[Action.Circle](step,pos)
	// }
	static [Action.Ellipse](step,pos){
		let fp =step[0]
		let lp =step[1]
		let dx = Math.abs(fp.x-lp.x)
		let dy = Math.abs(fp.y-lp.y)
	
		let pdx = Math.abs(pos.x-fp.x)
		let pdy = Math.abs(pos.y-fp.y)

		let t = dx>dy
		if(t)
			pdy*=(dx/dy)
		else 
			pdx*=(dy/dx)
		
		let r = Math.max(dx,dy)
		let r1 = Math.pow(pdx*pdx+pdy*pdy,0.5)

		let c1 = Math.abs(r1-r)<fp.r
		let c2 = Math.distance(fp,pos)<fp.r
		let c3 = false
		// if(pos.pathMode)
			c3 = Math.distance(lp,pos)<fp.r
		return c1||c2||c3
	}
	// ************************line line line start
	static [Action.PointLine](step,pos){
		let fp = step[0]
		return Math.point_line(fp,pos)<fp.r
	}
	static [Action.Linend](step,pos){
		return Math.foldlineInPath(step,pos,true)
	}
	static [Action.Ray](step,pos){
		let fp = step[0]
		let sp = step[1]
		let {width,height} = document.pageRect()
		let dim = Math.dim(width,height)
		let a = Math.tan360(sp.y-fp.y,sp.x-fp.x)
		let rp = Math.rotatePos({x:dim+fp.x,y:fp.y},fp,a)
		return Math.foldlineInPath([fp,rp],pos,true)
	}
	static [Action.Line](step,pos){
		return Math.foldlineInPath(step,pos)
	}
	static [Action.CutLine](step,pos){
		let steps = [step[1],step[0],step[2]]
		return Math.foldlineInPath(steps,pos,true)
	}
	static [Action.Foldline](steps,pos){
		return Math.foldlineInPath(steps,pos,true)
	}
	static [Action.Polygon](step,pos,state){
		let cp = step[0]
		let c1 = Math.distance(cp,pos)<cp.r
		let steps = Math.getPolyPos(step,state.n).map(p=>{
			p.r=cp.r
			p.text=p.text||""
			return p
		})
		let c2 = Math.foldlineInPath([...steps,steps[1]],pos,true)
		return c1||c2
	}
	static [Action.Rect](step,pos){
		let rect = Math.rect(step[0],step[1]).map(p=>p.assign({r:Web.r}))
		return Math.foldlineInPath([...rect,rect[0]],pos,true)
	}
	// *************************line line line end
	// *************************point point point start
	static [Action.Point](step,pos){
		return Math.distance(step[0],pos)<step[0].r
	}
	// static [Action.mirror](step,pos){
	// 	return Math.distance(step[0],pos)<Web.r
	// }
	static [Action.Pen](steps,pos){
		return steps.some((p)=>Math.distance(p,pos)<Web.r)
	}
	static anonymous(){
		return false
	}
	static findIndex(step,pos){
		return step.findIndex(d=>{
			return d.move&&Math.distance(pos,d) < Web.r
		})
	}
}